import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Map;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSItem;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class CorruptScriptsBlackDragonRanger extends Script implements
		PaintListener, ServerMessageListener {

	RSTile[] SAFE_SPOT = new RSTile[] { new RSTile(2835, 9820) };

	public boolean SPECIAL;
	public static int[] projectiles = { 864 }; // 864, bronze knives
	public int law = 563;
	public int air = 556;
	public int vial = 229;
	public boolean telegrab;
	public boolean dopotion;
	public int failPotting = 0;
	public int PD;
	public int[] rangedPot = { 173, 171, 169, 2444 };
	// new int[]
	public long startTime = System.currentTimeMillis();
	int startxp = skills.getCurrentSkillExp(4);
	int startlvl = skills.getRealSkillLevel(4);
	int[] StrangePlants = new int[] { 407, 408 };
	boolean pickFruit = true;

	private final int BoneID = 536;

	private final int BowlID = 1923;

	public void antiban() {
		setRun(false);
		checkForRandoms();
		getEat();
		BuryBones();
		DropBowls();
		wait(random(800, 1400));

		if (getCurrentTab() == Constants.TAB_INVENTORY) {
			atInventoryItem(vial, "Drop");
		}

		if (random(0, 100) < 15) {
			final int variable = random(1, 3);
			switch (variable) {
			case 1:
				moveMouse(random(-1, 764), random(-1, 499));
			case 2:
				final int rando = random(1, 4);
				switch (rando) {
				case 1:
					openTab(Constants.TAB_INVENTORY);
					wait(random(1000, 12000));
				case 2:
					openTab(Constants.TAB_PRAYER);
					wait(random(1000, 12000));
				case 3:
					openTab(Constants.TAB_STATS);
					wait(random(1000, 12000));
				case 4:
					return;
				}
			case 3:
				final int thingy = random(1, 2);
				if (thingy == 1) {
					setRun(true);
				} else {
					setRun(false);
				}
			}
		}
		if (getCurrentTab() != Constants.TAB_MAGIC) {
			if (getCurrentTab() != Constants.TAB_INVENTORY) {
				if (getCurrentTab() != Constants.TAB_ATTACK) {
					wait(random(8000, 12000));
					openTab(Constants.TAB_INVENTORY);
					return;
				}
			}
		}
	}

	private boolean atInventoryItemMx(final int[] itemID, final String option) {
		if (getCurrentTab() != Constants.TAB_INVENTORY
				&& !RSInterface.getInterface(Constants.INTERFACE_BANK)
						.isValid()
				&& !RSInterface.getInterface(Constants.INTERFACE_STORE)
						.isValid()) {
			openTab(Constants.TAB_INVENTORY);
		}
		final int[] items = getInventoryArray();
		final java.util.List<Integer> possible = new ArrayList<Integer>();
		for (final int element : itemID) {
			for (int i = 0; i < items.length; i++) {
				if (items[i] == element) {
					possible.add(i);
				}
			}
		}
		if (possible.size() == 0) {
			return false;
		} else {
			final int IDE = random(0, possible.size());
			final int idx = possible.get(IDE);
			final Point t = getInventoryItemPoint(idx);
			clickMouseMx(t, 5, 5, false);
			return atMenu2(option);
		}
	}

	public boolean atMenu2(final String optionContains) {
		int idx = getMenuIndex(optionContains);
		if (!isMenuOpen()) {
			if (idx == -1) {
				return false;
			}
			if (idx == 0) {
				clickMouse(true);
			} else {
				clickMouse(false);
				atMenuItem(idx);
			}
			return true;
		} else {
			if (idx == -1) {
				idx = getMenuIndex("Cancel");
				atMenuItem(idx);
				return false;
			} else {
				atMenuItem(idx);
				return true;
			}
		}
	}

	public void BuryBones() {
		openTab(Constants.TAB_INVENTORY);

		wait(random(200, 400));
		moveMouse(633, 338);
		atInventoryItem(BoneID, "Bury");

	}

	public boolean checkForPlant() {
		final RSNPC ThatDamnPlant = getNearestNPCByID(StrangePlants);
		if (ThatDamnPlant == null) {
			return true;
		}
		return false;
	}

	public void checkForRandoms() {
		if (!pickFruit) {
			pickFruit = checkForPlant();
		}
		HandleStrangePlant();
	}

	void clickMouseMx(final int x, final int y, final boolean leftClick) {
		clickMouseMx(x, y, 0, 0, leftClick);
	}

	void clickMouseMx(final int x, final int y, final int width,
			final int height, final boolean leftClick) {
		moveMouse(x, y, width, height);
		wait(random(40, 100));
		input.clickMouse(leftClick);
	}

	void clickMouseMx(final Point p, final boolean leftClick) {
		clickMouseMx(p.x, p.y, leftClick);
	}

	void clickMouseMx(final Point p, final int x2, final int y2,
			final boolean leftClick) {
		clickMouse(p.x, p.y, x2, y2, leftClick);
	}

	public void doSpecial() {
		if (getSpecial() == 1000 && SPECIAL) {
			openTab(Constants.TAB_ATTACK);
			clickMouse(645 + random(0, 4), 425 + random(0, 4), true);
			wait(3000);
			openTab(Constants.TAB_INVENTORY);
		}
		return;
	}

	public void DropBowls() {
		openTab(Constants.TAB_INVENTORY);

		wait(random(200, 400));
		moveMouse(633, 338);
		atInventoryItem(BowlID, "Drop");

	}

	private void eat(final int id) {
		eat_check();

		log("Eating: Curry.");
		atInventoryItem(id, "Eat");

		wait(random(1500, 2500));

		atInventoryItem(vial, "Drop");
		return;
	}

	private void eat_check() {
		final RSItem food = getInventoryItemByID(2011);
		if (getInventoryCount(2011) >= 1) {
			eat(food.getID());
		} else {
			log("Out of food... Way to safe spot");
			logout();
			stopAllScripts();
		}
		return;
	}

	@Override
	public String getAuthor() {
		return "Bug5532/Modified Corrupt/Coco";
	}

	private void getEat() {
		if (skills.getCurrentSkillLevel(3) < 30) {
			eat(2011);

		}
	}

	@Override
	public String getName() {
		return "Black Drag Ranger - Corrupt";
	}

	@Override
	public String getScriptCategory() {
		return "Combat";
	}

	@Override
	public String getScriptDescription() {
		String html = "";

		html += "<html>";
		html += "<head>";
		html += "<style type=\"text/css\"> hr {color: sienna} p {margin-left: 20px} body </style>";
		html += "</head>";
		html += "<body>";
		html += "<center>";
		html += "<br>";
		html += "To Start put your account infront of the Black Dragons with Range equipment Equipped. Will eat Curry, so take it incase, and wear ring of life, (Curry is for health when reaches 30-40).<br>";

		html += "<b>Features:</b><br>";
		html += "-Attacks Black Dragons<br>";
		html += "-Need atleast 28 Tele-grab spells.<br>";
		html += "-Logs out if it reaches Lumbridge coords<br><br>";
		html += "Edited by <b>Corrupt</b>:<br>";
		html += "- Added Tele-grab to Dragon bones.<br>";
		html += "- Added Tele-grab to Black Dragonhide.<br>";
		html += "- Added ranging potions support.<br>";
		html += "- Added safe spot support.<br>";

		html += "<input type=\"checkbox\" name=\"TELE\" value=\"true\" checked=\"checked\">Telegrab ranarr seed(air and law on inv)<p>";
		html += "<input type=\"checkbox\" name=\"POT\" value=\"true\" checked=\"checked\">Drink ranging pot<p>";
		html += "<input type=\"checkbox\" name=\"SPEC\" value=\"true\" checked=\"checked\">Do special attack.<p>";

		html += "<b>Future Updates:</b><br>";
		html += "- Banking Dragon bones and Black dragonhides.<br>";
		html += "- Falador Teleport Method<br>";
		html += "<b>Version: 2.6.2</b><br>";

		html += "</center>";
		html += "</body>";
		html += "</html>";

		return html;
	}

	public int getSpecial() {
		return getSetting(300);
	}

	@Override
	public double getVersion() {
		return 1.00;
	}

	public void HandleStrangePlant() {
		final RSNPC ThatDamnPlant = getNearestNPCByID(StrangePlants);

		if (pickFruit && ThatDamnPlant != null
				&& distanceTo(ThatDamnPlant.getLocation()) <= 2) {
			atNPC(ThatDamnPlant, "Pick");
			wait(random(1500, 200));
		}
	}

	@Override
	public int loop() {

		if (getMyPlayer().getLocation().equals(SAFE_SPOT)
				&& getMyPlayer().getInteracting() == null
				&& getNearestFreeNPCByID(4673) != null) {
			atNPC(getNearestFreeNPCByID(4673), "Attack");
		}

		if (RSInterface.getInterface(740).isValid()) {
			atInterface(RSInterface.getInterface(740).getChild(3));
			return random(100, 1500);
		}
		if (getInventoryCount(CorruptScriptsBlackDragonRanger.projectiles) != 0) {
			log("equipping projectiles");
			atInventoryItemMx(CorruptScriptsBlackDragonRanger.projectiles,
					"Wield");
		}

		if (telegrab) {
			SupahTelegrab();
		}

		if (SPECIAL) {
			doSpecial();
		}
		if (dopotion) {
			if (skills.getCurrentSkillLevel(4) != skills.getRealSkillLevel(4)) {
			} else {
				// actual level is same as real level, pot effects OFF!
				if (getInventoryCount(rangedPot) != 0) {
					log("lets drink a pot");
					atInventoryItemMx(rangedPot, "Drink");
					wait(1800);
					PD++;
				} else {
					if (failPotting > 3) {
						log("No more pots");
						dopotion = false;
					} else {
						failPotting++;
						log("Failed potting");
					}
				}
			}
		}

		if (getMyPlayer().getInteracting() == null) {
			if (getMyPlayer().getAnimation() != -1) {
				return random(200, 300);
			}
			final RSNPC ogre = getNearestFreeNPCByID(4673);
			wait(110);

			if (ogre != null) {
				atNPC(ogre, "Attack");
				wait(50);
				return random(10, 80);
			}
			wait(800);
			log("Findind Black Dragon");
			wait(800);
		} else {
			antiban();
		}
		return random(50, 150);
	}

	@Override
	public void onFinish() {
		Bot.getEventManager().removeListener(PaintListener.class, this);
		Bot.getEventManager().removeListener(ServerMessageListener.class, this);
	}

	public void onRepaint(final Graphics g) {
		if (isLoggedIn()) {
			long millis = System.currentTimeMillis() - startTime;
			final int XPChange = skills.getCurrentSkillExp(4) - startxp;
			final long hours = millis / (1000 * 60 * 60);
			millis -= hours * 1000 * 60 * 60;
			final long minutes = millis / (1000 * 60);
			millis -= minutes * 1000 * 60;
			final long seconds = millis / 1000;

			final int LevelChange = skills.getRealSkillLevel(4) - startlvl;
			final int nextLevel = skills.getRealSkillLevel(4) + 1;

			float expPerSec = 0;
			if ((minutes > 0 || hours > 0 || seconds > 0) && XPChange > 0) {
				expPerSec = (float) XPChange
						/ (float) (seconds + minutes * 60 + hours * 60 * 60);
			}
			final float expPerMin = expPerSec * 60;
			final float expPerHour = expPerMin * 60;

			g.setColor(Color.WHITE);
			g.setFont(new Font("Comic Sans", Font.BOLD, 12));
			g.drawString("Corrupt's Black Dragon Ranger V 2.6.2", 275, 273);
			g.drawString("Ranging Pot Used: " + PD, 275, 286);
			g.drawString("Runtime: " + hours + " hours " + minutes
					+ " minutes " + seconds + " seconds.", 275, 298);
			g.drawString("Gained " + LevelChange + " range level ("
					+ skills.getRealSkillLevel(4) + ") and " + XPChange
					+ " exp.", 275, 310);
			g.drawString("Exp to lvl " + nextLevel + ": "
					+ skills.getXPToNextLevel(4), 275, 322);
			g.drawString("Exp Per Hour: " + (int) expPerHour, 275, 334);
		}
	}

	@Override
	public boolean onStart(final Map<String, String> args) {
		SPECIAL = false;
		vial = 229;
		failPotting = 0;
		telegrab = false;
		dopotion = false;
		skills.getCurrentSkillExp(4);
		skills.getRealSkillLevel(4);

		if (args.get("POT") != null) {// checking if checkbox "exist" (only
			// "exist" if checked)
			dopotion = true;
			log("Potting");
		} else { // not checked.
			dopotion = false;
			log("Not potting");
		}

		if (args.get("SPEC") != null) { // yu`p
			SPECIAL = true;
			log("doing special attack");
		} else {
			SPECIAL = false;
			log("Not doing specials");
		}

		if (args.get("TELE") != null) {// same here
			telegrab = true;
			log("Telegrabing");
		} else {
			telegrab = false;
			log("Not teleing");
		}
		return true;
	}

	public void serverMessageRecieved(final ServerMessageEvent e) {
		final String mes = e.getMessage();
		if (mes.contains("There is no ammo left in your quiver.")) {
			logout();
			stopAllScripts();
		}
		if (mes.contains("That was your last one!")) {
			logout();
			log("bye, last one");
		}
	}

	public int SupahTelegrab() {

		final RSTile RSEED = getGroundItemByID(536); // D Bones
		final RSTile WSEED = getGroundItemByID(1747); // Black D Hide
		final RSTile SSEED = getGroundItemByID(563); // Laws

		if (!telegrab) {
			return -1;
		}
		if (!inventoryContains(law)) {
			telegrab = false;
			log("Out of law runes.");
			return -1;
		}
		if (!inventoryContains(air)) {
			log("Out of air runes.");
			telegrab = false;
			return -1;
		}
		if (WSEED != null) {
			if (getCurrentTab() != Constants.TAB_MAGIC) {
				openTab(Constants.TAB_MAGIC);
			}
			wait(400);
			clickMouse(716 + random(-7, 7), 275 + random(-6, 6), true);
			wait(1120);
			atTile(WSEED, "Cast Telekinetic Grab -> Black dragonhide");
			wait(2100);
			openTab(Constants.TAB_INVENTORY);
			return 0;
		}

		if (SSEED != null) {
			if (getCurrentTab() != Constants.TAB_MAGIC) {
				openTab(Constants.TAB_MAGIC);
			}
			wait(400);
			clickMouse(716 + random(-7, 7), 275 + random(-6, 6), true);
			wait(420);
			atTile(SSEED, "Cast Telekinetic Grab -> Law rune");
			wait(2100);
			openTab(Constants.TAB_INVENTORY);
		}
		if (RSEED != null) {
			if (getCurrentTab() != Constants.TAB_MAGIC) {
				openTab(Constants.TAB_MAGIC);
			}
			wait(400);
			clickMouse(716 + random(-7, 7), 275 + random(-6, 6), true);
			wait(420);
			atTile(RSEED, "Cast Telekinetic Grab -> Dragon bone");
			wait(2100);
			openTab(Constants.TAB_INVENTORY);

		}
		return 0;
	}
}